﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PlayerInterface;



namespace ControllerLib
{
    class MyBoom //与自己放置的炸弹相关
    {
        float[,] myBoom = new float[10, 3]; //x,y,setTime

        public MyBoom()
        {
            for (int i = 0; i < 10; i++) myBoom[i, 2] = 0;
        }

        int update(float nowTime) //检查炸弹是否过期并返回一个可用空位(0表示无空位)
        {
            int canSetBoom = 0;
            for (int i = 0; i < 10; i++)
            {
                if (myBoom[i, 3] != 0 && myBoom[i, 3] - nowTime > 3)
                {
                    myBoom[i, 3] = 0;
                    canSetBoom = i;
                }
            }
            if (canSetBoom != 0) return canSetBoom;
            for (int i = 0; i < 10; i++)
            {
                if (myBoom[i, 3] == 0) return i;
            }
            return 0;
        }
        public bool setNewBoom(int x, int y, float nowTime)
        {
            int target = update(nowTime);
            if (target != 0)
            {
                myBoom[target, 0] = x;
                myBoom[target, 1] = y;
                myBoom[target, 2] = nowTime;
                return true;
            }
            return false;
        }
        public float isThatMyBoom(int x, int y, float nowTime) //查询是否是自己放置的炸弹，-1表示不是，否则返回此炸弹的剩余时间
        {
            update(nowTime);
            for (int i = 0; i < 10; i++)
            {
                if (myBoom[i, 0] == x && myBoom[i, 1] == y && myBoom[i, 2] != 0) return myBoom[i, 2] - nowTime;
            }
            return -1;
        }
    }


    class SafeState
    {
        int safeState; //当前状态安全级别，0表示无任何危险，1表示可能受到炸弹的威胁，2表示需要躲开毒区，3表示立即躲开炸弹
        public void setSafeState(int x)
        {
            if (safeState < x) safeState = x;
        }
        public int getSafeState()
        {
            return safeState;
        }
        public void resetSafeState()
        {
            safeState = 0;
        }
    }
    struct BetterMap
    {
        //1=>x-1,3=>z-1
        public bool[] openTime;//四个方向的访问记录

        public int startDrt; //携带需要到达此处出发时应走的方向
        public int startJudge; //如果以此处作为目的地，则judge和的最小值

        public int judge; //对该点的评估
    }
    class Controller : PlayerInterface.IControl
    {
        const int playerIndex = 1;//玩家序号
        int[] position; //当前玩家坐标
        int?[,,] nearByMap = new int?[3, 3, 2]; //玩家身边的3x3网格信息
        //第三维度的第一层，从0开始递增（标准步长为2）表示方格危险程度，可能的炸弹威胁+1，严重的炸弹威胁+2，毒区+1，不可用+20
        //第三维度的第二层，标识地图上的相关物品，0空地，1可炸，2不可炸，3炸弹，大于3表示此处重叠了其他玩家，减去4可得此处物品
        int? mapTemp; //暂存获取到的地图信息，-1表示不可用，0空地，1可炸，2不可炸，3炸弹，null表示查询非法
        MyBoom myboon;//存放自己放置的炸弹
        SafeState safeState;

        public string GetTeamName()
        {
            return "Cno Shabby AI 1";
        }

        public void Update(IEntity entity)
        {
            if (entity.IsMoving()) return;
            position = entity.GetPosition();
            safeState.resetSafeState();
            Array.Clear(nearByMap, 0, nearByMap.Length);
            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) //获取自己周围3x3网格信息
                {
                    if (i == 2 && j == 2) continue;
                    mapTemp = entity.GetMapType(position[0] + i - 1, position[1] + j - 1);

                    //==============================================================================================================物体标识
                    if (mapTemp == 2 || mapTemp == 3) nearByMap[i, j, 1] += 20;
                    nearByMap[i, j, 2] = mapTemp;
                    //==============================================================================================================异常处理
                    if (mapTemp == 3)  //发现炸弹
                    {
                        float isTMB = myboon.isThatMyBoom(position[0] + i - 1, position[1] + j - 1, entity.GetRemainingTime());
                        if (isTMB != -1)
                        {
                            //自己放的炸弹
                            if (entity.PlayerBuffing(playerIndex, 2) == true)
                            {
                                //作为buf炸弹标记
                                for (int k = -1; k <= 1; k++) for (int q = -1; q <= 1; q++)
                                    {
                                        if (i + k >= 0 && i + k < 3 && j + q >= 0 && j + q < 3)
                                        {
                                            if (isTMB > 2)
                                            {
                                                nearByMap[i + k, j + q, 1]++;
                                                if (i + k == position[0] && j + q == position[1]) safeState.setSafeState(1);
                                            }
                                            else
                                            {
                                                nearByMap[i + k, j + q, 1] += 2;
                                                if (i + k == position[0] && j + q == position[1]) safeState.setSafeState(3);
                                            }
                                        }
                                    }
                            }
                            else
                            {
                                //作为普通炸弹标记
                                for (int k = -1; k <= 1; k++) for (int q = -1; q <= 1; q++)
                                    {
                                        if (k + q != 1 && k + q != -1) continue;
                                        if (i + k >= 0 && i + k < 3 && j + q >= 0 && j + q < 3)
                                        {
                                            if (isTMB > 2)
                                            {
                                                nearByMap[i + k, j + q, 1]++;
                                                if (i + k == position[0] && j + q == position[1]) safeState.setSafeState(1);
                                            }
                                            else
                                            {
                                                nearByMap[i + k, j + q, 1] += 2;
                                                if (i + k == position[0] && j + q == position[1]) safeState.setSafeState(3);
                                            }
                                        }
                                    }
                            }
                        }
                        else
                        {
                            //其他玩家放的炸弹
                            bool hasBuf = false;
                            for (int iy = 1; iy < 5; iy++)
                            {
                                if (iy == playerIndex) continue;
                                if (entity.PlayerBuffing(iy, 2) == true)
                                {
                                    hasBuf = true;
                                    break;
                                }
                            }
                            if (hasBuf)
                            {
                                //作为buf炸弹标记
                                for (int k = -1; k <= 1; k++) for (int q = -1; q <= 1; q++)
                                    {
                                        if (i + k >= 0 && i + k < 3 && j + q >= 0 && j + q < 3)
                                        {
                                            nearByMap[i + k, j + q, 1] += 2;
                                            if (i + k == position[0] && j + q == position[1]) safeState.setSafeState(3);
                                        }
                                    }
                            }
                            else
                            {
                                //作为普通炸弹标记
                                for (int k = -1; k <= 1; k++) for (int q = -1; q <= 1; q++)
                                    {
                                        if (k + q != 1 && k + q != -1) continue;
                                        if (i + k >= 0 && i + k < 3 && j + q >= 0 && j + q < 3)
                                        {
                                            nearByMap[i + k, j + q, 1] += 2;
                                            if (i + k == position[0] && j + q == position[1]) safeState.setSafeState(3);
                                        }
                                    }
                            }
                        }

                    }
                    //炸弹处理完毕



                    if (entity.GetRemainingTime() < 30) //缩圈警告
                    {
                        float remainingTime = entity.GetRemainingTime();
                        if (remainingTime > 25)
                        {
                            if (position[0] + i - 1 == 0 || position[0] + i - 1 == 9 || position[1] + j - 1 == 0 || position[1] + j - 1 == 9)
                            {
                                nearByMap[i, j, 1] += 1;
                                safeState.setSafeState(2);
                            }
                        }
                        else if (remainingTime > 15)
                        {
                            if (position[0] + i - 1 == 1 || position[0] + i - 1 == 8 || position[1] + j - 1 == 1 || position[1] + j - 1 == 8)
                            {
                                nearByMap[i, j, 1] += 1;
                                safeState.setSafeState(2);
                            }
                            else if (position[0] + i - 1 == 0 || position[0] + i - 1 == 9 || position[1] + j - 1 == 0 || position[1] + j - 1 == 9)
                            {
                                nearByMap[i, j, 1] += 20;
                                nearByMap[i, j, 2] = 2;
                            }
                        }
                        else if (remainingTime > 5)
                        {
                            if (position[0] + i - 1 == 2 || position[0] + i - 1 == 7 || position[1] + j - 1 == 2 || position[1] + j - 1 == 7)
                            {
                                nearByMap[i, j, 1] += 1;
                                safeState.setSafeState(2);
                            }
                            else if (position[0] + i - 1 == 0 || position[0] + i - 1 == 9 || position[1] + j - 1 == 0 || position[1] + j - 1 == 9 || position[0] + i - 1 == 1 || position[0] + i - 1 == 8 || position[1] + j - 1 == 1 || position[1] + j - 1 == 8)
                            {
                                nearByMap[i, j, 1] += 20;
                                nearByMap[i, j, 2] = 2;
                            }
                        }
                    }

                }
            //==================================================================================其他玩家标识
            int[] pstTemp;
            int xTemp, yTemp;
            for (int ik = 1; ik <= 4; ik++)
            {
                if (ik == playerIndex) continue;
                pstTemp = entity.PlayerPosition(ik);
                xTemp = pstTemp[0] - position[0];
                yTemp = pstTemp[1] - position[1];
                if (xTemp >= -1 && xTemp <= 1 && yTemp >= -1 && yTemp <= 1)
                {
                    nearByMap[xTemp + 1, yTemp + 1, 2] += 4;
                }
            }

            //==================================================================================对不同的安全等级采取措施
            switch (safeState.getSafeState())
            {
                case 3://躲开炸弹
                    //生成一个5x5的附近地图并计算权重，选择最佳路径逃跑
                    BetterMap[,] runMap = new BetterMap[5, 5];
                    Array.Clear(runMap, 0, runMap.Length);
                    for (int i = 0; i < 5; i++) for (int j = 0; j < 5; j++)
                        {
                            mapTemp = entity.GetMapType(position[0] + i - 2, position[1] + j - 2);
                            switch (mapTemp)
                            {
                                case -1:
                                    runMap[i, j].judge += 20;
                                    break;
                                case 0:
                                    break;
                                case 1: //箱子附近将成为洼地
                                    for (int k = -1; k <= 1; k++) for (int q = -1; q <= 1; q++)
                                        {
                                            if (k + q == -2 || k + q == 0 || k + q == 2) continue;
                                            runMap[i + k, j + q].judge -= 2;
                                        }
                                    break;
                                case 2:
                                    runMap[i, j].judge += 20;
                                    break;
                                case 3: //炸弹附近将成为高地
                                    for (int k = -1; k <= 1; k++) for (int q = -1; q <= 1; q++)
                                        {
                                            runMap[i + k, j + q].judge += 1;
                                        }
                                    runMap[i, j].judge += 20;
                                    break;
                                default:
                                    runMap[i, j].judge += 20;
                                    break;
                            }
                        }
                    //5x5信息收集完毕，使用DFS查找最佳路径（与目的地）

                    break;
                case 2://跑毒
                    break;
                case 1:
                case 0://全局查找箱子
                    break;
                default:
                    break;
            }



            return;
        }
    }
}
